package piece;
/*
 * Justin Prentice
 * TCSS 305 (winter quarter)
 * Tetris program - LPiece test
 */

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * A test of the LPiece class.
 * @author Justin Prentice
 * @version 1.0
 *
 */
public class LPieceTest
{
  
  /**
   * a LPiece for testing.
   */
  private LPiece my_test_piece;

  /**
   * Sets up a second LPiece for testing.
   */
  private LPiece my_other_piece;
  
  /**
   * Sets up 2 LPieces for testing.  
   */
  @Before
  public void initialize()
  {
    my_test_piece = new LPiece();
    my_other_piece = new LPiece();
  }
  
  /**
   * Tests the clone() method.
   * @throws CloneNotSupportedException throws an exception if clone is not supported.
   */
  @Test
  public void testClone() throws CloneNotSupportedException
  {
    
    final LPiece clone = (LPiece) my_test_piece.clone();
    assertEquals("The pieces should have the same X coordinate", 
                 my_test_piece.getX(), clone.getX());
    assertEquals("The pieces should have the same Y coordinate",
                 my_test_piece.getY(), clone.getY());
    assertArrayEquals("The state of the pieces should be the same",
                      my_test_piece.getState(), clone.getState());
  }

  /**
   * Tests the left() method.
   */
  @Test
  public void testLeft()
  {
    my_other_piece.left();
    assertSame("The left() method should reduce the x coordinate by 1", 
               my_test_piece.getX() - 1, my_other_piece.getX());
    
  }

  /**
   * Tests the right() method.
   */
  @Test
  public void testRight()
  {
    my_other_piece.right();
    assertSame("The right() method should increase the x coordinate by 1", 
               my_test_piece.getX() + 1, my_other_piece.getX());
  }

  /**
   * Tests the down() method.
   */
  @Test
  public void testDown()
  {
    my_other_piece.down();
    assertSame("The down() method should increase the y coordinate by 1",
               my_test_piece.getY() + 1, my_other_piece.getY());
  }

  /**
   * Tests the rotate() method.
   */
  @Test
  public void testRotate()
  {
    final boolean[][][] possible_rotations = {{{true, true, true, false}, 
                                               {true, false, false, false}, 
                                               {false, false, false, false}, 
                                               {false, false, false, false}}, 
                                        
                                              {{false, true, true, false}, 
                                               {false, false, true, false}, 
                                               {false, false, true, false}, 
                                               {false, false, false, false}},
                                              
                                              {{false, false, true, false}, 
                                               {true, true, true, false}, 
                                               {false, false, false, false}, 
                                               {false, false, false, false}},
                                            
                                              {{true, false, false, false}, 
                                               {true, false, false, false}, 
                                               {true, true, false, false}, 
                                               {false, false, false, false}}};
    
    for (int i = 0; i < 5; i++) //4 rotations to test going back to original state
    {
      assertArrayEquals("The returned rotation does not match expected: " + i, 
                   possible_rotations[i % 4], my_test_piece.getState());
      my_test_piece.rotate();
    }
  }

  /**
   * Tests the getState() method.
   */
  @Test
  public void testGetState()
  {
    assertNotSame("The arrays returned should not be shallow copies.", 
                my_test_piece.getState() == my_test_piece.getState());
  }
  
  /**
   * Tests the toString method.
   */
  @Test
  public void testToString()
  {
    assertEquals("The toString does not match the expected string", 
                 "LPiece:\nxxx \nx   \n    \n    \n" , my_test_piece.toString());
  }

}
